﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace gpuimp.core
{
    public static class ConfigManager
    {
        /**
         * ReadConfigFile takes in a XML file.
         * The file can contain data for either making a new tool, configuring a current tool, or creating a macro.
         * ReadConfigFile will then parse out the appropriate data
         * */
        public static void ReadConfigFile(string configFileName)
        {
            #region ReadConfigFile
            try
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(configFileName);

                #region flags
                //flags to know what type of xml node is being read
                bool readingTool = false;
                bool readingToolConfig = false;
                bool readingMacro = false;
                bool readingToolConfigList = false;
                #endregion

                
                foreach (XmlNode node in doc.DocumentElement.ChildNodes)
                {
                
                    readingTool = (node.Name == "Tool");
                    readingToolConfig = (node.Name == "ConfigTool");
                    readingMacro = (node.Name == "Macro");
                    readingToolConfigList = (node.Name == "ConfigToolList");

                    if (readingTool)
                    {
                        getToolAttributes(node);
                    }

                    if (readingToolConfig)
                    {
                        getToolConfigAttributes(node);
                    }
                 
                    if (readingMacro)
                    {
                        getMacro(node);
                    }

                    if (readingToolConfigList)
                    {
                        foreach (XmlNode childNode in node.ChildNodes)
                        {
                            getToolConfigAttributes(childNode);
                        }
                    }
                }
            }
            #region catches
            //catches to make sure the file is there
            catch (FileNotFoundException e)
            {
                Console.WriteLine(e);
            }
            catch (FileLoadException e)
            {
                Console.WriteLine(e);
            }
            #endregion 
            #endregion
        }

        /**
         * getToolAttributes reads in a Tool Node from an Xml file.
         * It then parses out all the viable information from the node and converts them
         * to the proper object type.
         * */
        private static void getToolAttributes(XmlNode node)
        {
            #region getToolAttributes
            //read in node attributes
            XmlAttribute fragProg = node.Attributes["fragProg"];
            XmlAttribute vertProg = node.Attributes["vertProg"];
            XmlAttribute icon = node.Attributes["icon"];
            XmlAttribute id = node.Attributes["id"];
            XmlAttribute name = node.Attributes["name"];
            XmlAttribute shader = node.Attributes["shader"];
            XmlAttribute copyShader = node.Attributes["copyShader"];
            XmlAttribute applying = node.Attributes["applying"];
            XmlAttribute type = node.Attributes["type"];

            //variables for the information in the node
            String TfragProg = "";
            String TvertProg = "";
            String Tname = "";
            String Ttype = "";
            int Tid;
            int Tshader;
            int TcopyShader;
            bool Tapplying = false;


            //parse out the info
            if (fragProg != null)
                TfragProg = fragProg.Value;
            if (vertProg != null)
                TvertProg = vertProg.Value;
            if (name != null)
                Tname = name.Value;
            if (Ttype != null)
                Ttype = type.Value;
            if (id != null)
                Tid = int.Parse(id.Value);
            if (shader != null)
                Tshader = int.Parse(shader.Value);
            if (copyShader != null)
                TcopyShader = int.Parse(copyShader.Value);
            if (applying != null)
                Tapplying = bool.Parse(applying.Value);

            //remove attrubutes from attribute list
            node.Attributes.Remove(fragProg);
            node.Attributes.Remove(vertProg);
            node.Attributes.Remove(name);
            node.Attributes.Remove(type);
            node.Attributes.Remove(id);
            node.Attributes.Remove(shader);
            node.Attributes.Remove(copyShader);
            node.Attributes.Remove(applying);
            #endregion
        }

        /**
         * getToolConfigAttributes reads in a ToolConfig Node from an Xml file.
         * It then parses out all the viable information from the node and converts them
         * to the proper object type.
         * */
        private static void getToolConfigAttributes(XmlNode node)
        {
            #region getToolConfigAttributes
            //read in node attributes
            XmlAttribute name = node.Attributes["Name"];
            XmlAttribute minSize = node.Attributes["minSize"];
            XmlAttribute maxSize = node.Attributes["maxSize"];
            XmlAttribute minOpacity = node.Attributes["minOpacity"];
            XmlAttribute maxOpacity = node.Attributes["maxOpacity"];
            XmlAttribute minScatter = node.Attributes["minScatter"];
            XmlAttribute maxScatter = node.Attributes["maxScatter"];
            XmlAttribute minColorVar = node.Attributes["minColorVar"];
            XmlAttribute maxColorVar = node.Attributes["maxColorVar"];
            XmlAttribute minHardness = node.Attributes["minHardness"];
            XmlAttribute maxHardness = node.Attributes["maxHardness"];

            //variables for the information in the node
            String TCname = "";
            float TCminSize = 1; 
            float TCmaxSize = 1; 
            float TCminOpac = 1; 
            float TCmaxOpac = 1; 
            float TCminScat = 1; 
            float TCmaxScat = 1; 
            float TCminVar = 1; 
            float TCmaxVar = 1;
            float TCminHard = 1;
            float TCmaxHard = 1;
            
            //parse out the info
            if(name != null)
                TCname = name.Value;
            if (minSize != null)
                TCminSize = float.Parse(minSize.Value);
            if (maxSize != null)
                TCmaxSize = float.Parse(maxSize.Value);
            if (minOpacity != null)
                TCminOpac = float.Parse(minOpacity.Value); 
            if (maxOpacity != null)
                TCmaxOpac = float.Parse(maxOpacity.Value);
            if (minScatter != null)
                TCminScat = float.Parse(minScatter.Value);
            if (maxScatter != null)
                TCmaxScat = float.Parse(maxScatter.Value);
            if (minColorVar != null)
                TCminVar = float.Parse(minColorVar.Value);
            if (maxColorVar != null)
                TCmaxVar = float.Parse(maxColorVar.Value);
            if (minHardness != null)
                TCminHard = float.Parse(minHardness.Value);
            if (maxHardness != null)
                TCmaxHard = float.Parse(maxHardness.Value);

            //remove attrubutes from attribute list
            node.Attributes.Remove(name);
            node.Attributes.Remove(minSize);
            node.Attributes.Remove(maxSize);
            node.Attributes.Remove(minOpacity);
            node.Attributes.Remove(maxOpacity);
            node.Attributes.Remove(minScatter);
            node.Attributes.Remove(maxScatter);
            node.Attributes.Remove(minColorVar);
            node.Attributes.Remove(maxColorVar);
            node.Attributes.Remove(minHardness);
            node.Attributes.Remove(maxHardness);

            //get attributes to the tool
            foreach(Tool tool in ToolManager.getList())
            {
                if (tool.getName() == TCname)
                {
                    tool.setMinSize(TCminSize);
                    tool.setMaxSize(TCmaxSize);
                    tool.setMinOpacity(TCminOpac);
                    tool.setMaxOpacity(TCmaxOpac);
                    tool.setMinScatter(TCminScat);
                    tool.setMaxScatter(TCmaxScat);
                    tool.setMinHardness(TCminHard);
                    tool.setMaxHardness(TCmaxHard);
                }
            }
            #endregion
        }

        /**
         * getMacro reads in a Macro Node from an Xml file.
         * It then parses out all the viable information from the node and converts them
         * to the proper object type.
         * */
        private static void getMacro(XmlNode node)
        {
            #region getMacro
            //read in node attributes
            XmlAttribute name = node.Attributes["name"];
            XmlAttribute macro = node.Attributes["macro"];

            //set variables
            String macName = "";
            String macCommand = "";

            //parse values
            if (name != null)
                macName = name.Value;
            if (macro != null)
                macCommand = macro.Value;

            //remove attributes from list
            node.Attributes.Remove(name);
            node.Attributes.Remove(macro);

            #endregion
        }
    }
}
